package pe.edu.upc.dsd.base.model.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.impl.CriteriaImpl;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


public abstract class BaseDaoImpl <D, PK extends Serializable> extends HibernateDaoSupport implements BaseDao <D,PK>{

	
	protected Class<D> tipo;
	
	@SuppressWarnings("unchecked")
	public BaseDaoImpl() {
		//super();
		ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
		this.tipo = (Class<D>) genericSuperclass.getActualTypeArguments()[0];
	}

	//@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public D crear(D entidad) {
		// TODO Auto-generated method stub
		getHibernateTemplate().saveOrUpdate(entidad);
		return entidad;
	}

	//@Override
	@Transactional(propagation = Propagation.REQUIRED)
	@SuppressWarnings("unchecked")
	public D obtener(PK id) {
		// TODO Auto-generated method stub
		return (D) getHibernateTemplate().get(tipo, id);
		
	}

	//@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public D modificar(D entidad) {
		// TODO Auto-generated method stub
		getHibernateTemplate().update(entidad);
		return entidad;
	}

	@Override
	public void eliminar(D entidad) {
		// TODO Auto-generated method stub
		getHibernateTemplate().delete(entidad);
		
	}

	//@Override
	@Transactional(propagation = Propagation.REQUIRED)
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public List<D> obtenerLista(final CriteriaImpl criteriaImpl) {
		// TODO Auto-generated method stub
		return (List<D>) this.getHibernateTemplate().execute(
				new HibernateCallback() {

					@Override
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						criteriaImpl.setSession( ( SessionImplementor ) session ); 
						criteriaImpl.setMaxResults(200);
						return criteriaImpl.list();
					}
				});
	}
}
